home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et3_0-a1.lha / et3 / src / PopupItem.C < prev    next >
C/C++ Source or Header  |  1992-08-26  |  7KB  |  311 lines

  1. #ifdef __GNUG__
  2. #pragma implementation
  3. #endif
  4.  
  5. #include "PopupItem.h"
  6.  
  7. #include "Class.h"
  8. #include "Menu.h"
  9. #include "SeqColl.h"
  10. #include "Look.h"
  11. #include "MenuBar.h"
  12. #include "TextItem.h"
  13. #include "WindowSystem.h"
  14. #include "Clipper.h"
  15. #include "Filler.h"
  16.  
  17. const int cPullRight= 16;
  18.  
  19. //---- MenuButton --------------------------------------------------------------
  20.  
  21. NewMetaImpl(MenuButton,StateButton, (TP(menu)));
  22.  
  23. MenuButton::MenuButton(int id, Menu *m) : StateButton(id)
  24. {
  25.     menu= m;
  26.     state= cIdNone;
  27.     SetFlag(eVObjVFixed|eVObjHFixed);
  28. }
  29.  
  30. MenuButton::~MenuButton()
  31. {
  32.     SafeDelete(menu);
  33. }
  34.  
  35. Menu *MenuButton::MyMenu()
  36. {
  37.     return menu;
  38. }
  39.  
  40. OStream& MenuButton::PrintOn(OStream &s)
  41. {
  42.     StateButton::PrintOn(s);
  43.     return s << menu SP;
  44. }
  45.  
  46. IStream& MenuButton::ReadFrom(IStream &s)
  47. {
  48.     StateButton::ReadFrom(s);
  49.     return s >> menu;
  50. }
  51.  
  52. void MenuButton::CollectParts(Collection* col)
  53. {
  54.     StateButton::CollectParts(col);
  55.     if (menu)
  56.     col->Add(menu);
  57. }
  58.  
  59. void MenuButton::SetCollection(SeqCollection *col, bool freeold)
  60. {
  61.     if (menu)
  62.     menu->SetCollection(col, freeold);
  63. }
  64.  
  65. //---- PopupButton -------------------------------------------------------------
  66.  
  67. NewMetaImpl0(PopupButton,MenuButton);
  68.  
  69. PopupButton::PopupButton(int id, int dfltid, Menu *m) : MenuButton(id, m)
  70. {
  71.     SetValue(dfltid, FALSE);
  72.     ResetFlag(eVObjHFixed);
  73. }
  74.  
  75. void PopupButton::SetContainer(VObject *v)
  76. {
  77.     MenuButton::SetContainer(v);
  78.     menu->SetNextHandler(this);
  79. }
  80.  
  81. void PopupButton::Control(int id, int part, void *v)
  82. {
  83.     if (id == cIdNone)
  84.     return;
  85.     if (part == cPartViewSize || part == cPartAnyChange)
  86.     return;
  87.     MenuButton::Control(id, part, v);
  88. }
  89.  
  90. Command *PopupButton::DispatchEvents(Point lp, Token &t, Clipper *vf)
  91. {
  92.     if (t.Code == eEvtLeftButton && !(t.Flags & eFlgButDown)) {
  93.     Command *currCmd= DoLeftButtonDownCommand(lp, t, WindowSystem::Clicks);
  94.     if (currCmd && currCmd != gNoChanges && vf)
  95.         currCmd= vf->TrackInContent(lp, t, currCmd);
  96.     return currCmd;
  97.     }
  98.     return MenuButton::DispatchEvents(lp, t, vf);
  99. }
  100.  
  101. Metric PopupButton::GetMinSize()
  102. {
  103.     if (menu) {
  104.     Metric m;
  105.     Iter next(menu->GetCollection());
  106.     register VObject *vop;
  107.     
  108.     while (vop= (VObject*) next())
  109.         m.Merge(vop->GetMinSize());
  110.     
  111.     return m.Expand(2);
  112.     }
  113.     return MenuButton::GetMinSize();
  114. }
  115.  
  116. void PopupButton::DoTrackMouse(TrackPhase atp, Point)
  117. {
  118.     if (Enabled() && atp == eTrackPress && menu) {
  119.     int id= menu->Popup(GetOrigin()+Point(0,-1), this, state, TRUE, TRUE, gRect0);
  120.     if (id != cIdNone) {
  121.         SetValue(id);
  122.         Control(GetId(), cPartToggle, (void*)id);
  123.     }
  124.     }
  125. }
  126.  
  127. void PopupButton::Draw(Rectangle r)
  128. {
  129.     VObject *v= menu->FindItem(state);
  130.     if (v == 0)
  131.     v= (VObject*)menu->GetCollection()->At(0);
  132.     if (v) {
  133.     int oldstate;
  134.     StateButton *stb= 0;
  135.     if (v->IsKindOf(StateButton))
  136.         stb= (StateButton*) v;
  137.     if (stb) {
  138.         oldstate= stb->GetValue();
  139.         stb->SetValue(0, FALSE);
  140.     }
  141.     state= v->GetId();
  142.     Point old(v->GetOrigin());
  143.     bool isopen= v->IsOpen();
  144.     if (!isopen)
  145.         v->Open();
  146.     v->SetOrigin(GetOrigin()+gPoint2);
  147.     v->SetExtent(GetExtent()-gPoint4);
  148.     v->DrawAll(r);
  149.     gLook->PopupButtonLayout()->Adorn(this, r, Enabled() ? 0 : 2);
  150.     v->SetOrigin(old);
  151.     if (!isopen)
  152.         v->Close();
  153.     if (stb)
  154.         stb->SetValue(oldstate, FALSE);
  155.     }
  156. }
  157.  
  158. //---- PullDownButton ----------------------------------------------------------
  159.  
  160. NewMetaImpl0(PullDownButton,MenuButton);
  161.  
  162. PullDownButton::PullDownButton(Menu *m) : MenuButton(cIdNone, m)
  163. {
  164.     if (m)
  165.     Add(new TextItem(m->GetName(), gSysFont, Point(8,2)));
  166. }
  167.  
  168. PullDownButton::PullDownButton(int id, Menu *m) : MenuButton(id, m)
  169. {
  170.     if (m)
  171.     Add(new TextItem(m->GetName(), gSysFont, Point(8,2)));
  172. }
  173.  
  174. extern bool gInButtonFlush;
  175.  
  176. void PullDownButton::DoTrackMouse(TrackPhase atp, Point)
  177. {
  178.     if (Enabled()) {
  179.     switch (atp) {
  180.     case eTrackPress:
  181.         Highlight(On);
  182.         state= cIdNone;
  183.         if (!gInButtonFlush && menu && Enabled()) {
  184.         state= menu->Popup(contentRect.SW(), this, cIdNone,
  185.             FALSE, TRUE,
  186.             Rectangle(Point(0, -contentRect.extent.y), contentRect.extent));
  187.         Highlight(Off);
  188.         }
  189.         break;
  190.     case eTrackRelease:
  191.         if (state >= 0) {
  192.         if (gFirstHandler) {
  193.             EvtHandler *old= gFirstHandler;
  194.             Command *cmd= gFirstHandler->DoMenuCommand(state);
  195.             gFirstHandler= old;
  196.             gFirstHandler->PerformCommand(cmd);
  197.         } else
  198.             PerformCommand(DoMenuCommand(state));
  199.         UpdateEvent();
  200.         }
  201.         Highlight(Off);
  202.         break;
  203.     case eTrackExit:
  204.         Highlight(Off);
  205.         break;
  206.     default:
  207.         break;
  208.     }
  209.     }
  210. }
  211.  
  212. void PullDownButton::DrawHighlight(Rectangle r)
  213. {
  214.     VObject::DrawHighlight(r);
  215. }
  216.  
  217. /*
  218. void PullDownButton::InputKbd(Token &t)
  219. {
  220.     if (Enabled() && Size() > 1) {
  221.     TextItem *ti= (TextItem*) At(1);
  222.     char *s= ti->AsString();
  223.     if (s && *s && upcase[s[1]] == upcase[t.Code & 0x7f])
  224.         Control(GetId(), cPartToggle, (void*) 1);
  225.     }
  226. }
  227.  
  228. int MenuBar::CheckKey(Token &t)
  229. {
  230.     int cmd= cIdNone;
  231.     Iter next(mb->MakeIterator());
  232.     register VObject *vop;
  233.     
  234.     while (vop= (VObject*) next()) {
  235.     if (vop->IsKindOf(PullDownButton)) {
  236.         PullDownButton *pdb= (PullDownButton*) vop;
  237.         cmd= pdb->Menu()->CheckKey(t);
  238.         if (cmd != cIdNone) {
  239.         pdb->Flush();
  240.         return cmd;
  241.         }
  242.     }
  243.     }
  244.     return cIdNone;
  245. }
  246. */
  247.  
  248. //---- MenuItem ----------------------------------------------------------------
  249.  
  250. NewMetaImpl(MenuItem,MenuButton, (T(lastxpos), T(enterxpos)));
  251.  
  252. MenuItem::MenuItem(int id, VObject *v, Menu *m) : MenuButton(id, m)
  253. {
  254.     Add(v);
  255. }
  256.  
  257. Metric MenuItem::GetMinSize()
  258. {
  259.     return gLook->MenuItemLayout()->GetMinSize(this);
  260. }
  261.  
  262. void MenuItem::DrawInner(Rectangle, bool highlight)
  263. {
  264.     int code= 0;
  265.     SETBIT(code, 4);
  266.     if (highlight)
  267.     SETBIT(code, 3);
  268.     if (Enabled())
  269.     SETBIT(code, 5);
  270.     gLook->MenuItemLayout()->Adorn(this, contentRect, code);
  271. }
  272.  
  273. void MenuItem::SetOrigin(Point at)
  274. {
  275.     VObject::SetOrigin(at);
  276.     gLook->MenuItemLayout()->SetOrigin(this, at);
  277. }
  278.  
  279. void MenuItem::DoTrackMouse(TrackPhase atp, Point p)
  280. {
  281.     if (Enabled() && menu) {
  282.     switch (atp) {
  283.     case eTrackPress:
  284.         Highlight(On);
  285.         enterxpos= lastxpos= p.x;
  286.         state= -1;
  287.         break;
  288.     case eTrackMove:
  289.     case eTrackIdle:
  290.         if (p.x > lastxpos && 
  291.             (p.x > enterxpos+cPullRight || p.x > At(0)->contentRect.E().x)) {
  292.         p.y= contentRect.W().y-2;
  293.         state= menu->Pulldown(p, this);
  294.         lastxpos= contentRect.SE().x+1;
  295.         } else
  296.         lastxpos= p.x;
  297.         break;
  298.     case eTrackRelease:
  299.     case eTrackExit:
  300.         if (state != cIdNone)
  301.         Control(state, cPartToggle, (void*)0);
  302.         Highlight(Off);
  303.     default:
  304.         lastxpos= contentRect.SE().x+1;
  305.         enterxpos= p.x;
  306.         break;
  307.     }
  308.     }
  309. }
  310.  
  311.